home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / PRUS101.ZIP / FCHARS.ASM < prev    next >
Assembly Source File  |  1994-12-19  |  14KB  |  442 lines

  1.  TITLE  FChars - Code fuer Turbo-Pascal-Funktionen zur
  2.  SUBTTL Bearbeitung von NUL-terminierten Strings im C-Format
  3.  
  4. ; goes along with FIDO unit to add Borland Pascal 7.0's Strings functions to
  5. ;               prior versions
  6. ; ***************************************************************************
  7.  
  8. ;       RELEASE 1.0 - as first contained in the file PRUS101.LZH
  9. ;             by Sieghard Schicktanz, 2:2480/642.25, GERMANY
  10.  
  11. ;              --------------------------------------------
  12. ;               organized for Fido's PASCAL related echoes
  13. ;              --------------------------------------------
  14.  
  15. ;  08/02/1994 to --/--/---- by Sieghard Schicktanz, 2:2480/642.25, GERMANY
  16.  
  17.  
  18. ;          As far as third party copyrights are not violated this
  19. ;          source code is hereby placed to the public domain. Use
  20. ;          it whatever way you want, but use AT YOUR OWN RISK.
  21.  
  22. ;          In case you should modify the source rather send your
  23. ;          modifications to the unit's current organizer (see above for
  24. ;          NM address) than to spread it on your own. This will help to
  25. ;          keep the unit updated and grant a certain standard to all
  26. ;          other users as well.
  27.  
  28. ;          The unit is currently still under work. So it might greatly
  29. ;          benefit of your participation.
  30.  
  31. ;          Those who contributed to the following piece of source,
  32. ;          listed in alphabethical order:
  33. ;       ================================================================
  34. ;          Andrew Eigus, Sieghard Schicktanz, ...
  35. ;       ================================================================
  36. ;          YOUR NAME WILL APPEAR HERE IF YOU CONTRIBUTE USEFUL SOURCE.
  37.  
  38. ;          Credits in your own programs are as welcome as unnecessary.
  39.  
  40. ; ***************************************************************************
  41.  
  42.         .MODEL  TPASCAL
  43.  
  44.         PUBLIC  Str2PChar, StrCat, StrComp, StrCopy, StrECopy
  45.         PUBlIC  StrEnd, StrLCat, StrLComp, StrLCopy
  46.         PUBlIC  StrLen, StrPas, StrRScan, StrScan, StrSkip
  47.                 ; %StrPCopy% implemented differently!
  48.  
  49. ; First, let's declare a couple of abbreviations and macros
  50. ;        that should make the code more readable
  51.  
  52. pntr    EQU     DWORD   ; this relates to the standard Pascal pointer type
  53. Rseg    EQU     DX      ; return registers used for
  54. Roff    EQU     AX      ; pointer values and
  55. Rint    EQU     AX      ; integer values by Turbo Pascal
  56.  
  57. SetUp   MACRO   Regs    ; this will be used to set up segment registers
  58.         LOCAL   @reg
  59.  
  60.         CLD
  61.   IRP   @reg, <Regs>
  62.         PUSH    @reg
  63.   ENDM
  64.  ENDM
  65.  
  66. CleanUp MACRO   Regs    ; this restores segments and returns cleanly
  67.         LOCAL   @reg
  68.  
  69.   IRP   @reg, <Regs>
  70.         POP     @reg
  71.   ENDM
  72.         RET
  73.  ENDM
  74.  
  75.  
  76.         LOCALS @@       ; tell the assembler how locals are marked
  77.  
  78. ; Now to the real thing - function code starts below
  79.  
  80.         .CODE           ; use this bloody segment
  81.  
  82.  
  83. Str2PChar PROC  FAR     source: pntr
  84. ; FUNCTION Str2PChar (str: string): PChar;
  85.  
  86.         SetUp   <DS, ES>
  87.         CLD
  88.         LES     DI, source              ; this is done in place!
  89.         LDS     SI, source              ; so target is same as source
  90.         SUB     CX, CX
  91.         LODSB                           ; get count byte
  92.         MOV     CL, AL
  93.         JCXZ    @@nix                   ; nothing to do?
  94.  
  95.         REP MOVSB                       ; move string down a notch
  96.         SUB     AL, AL                  ; and stick the NUL terminator
  97. @@nix:
  98.         STOSB                           ; to the end
  99.         LES     DI, source              ; now return
  100.         MOV     Rseg, ES                ; input address
  101.         MOV     Roff, DI                ; as output
  102.         CleanUp <ES, DS>
  103.  
  104. Str2PChar ENDP
  105.  
  106.  
  107. StrCat  PROC    FAR     dest: pntr, source: pntr
  108. ; FUNCTION StrCat (dest, source: PChar): PChar;
  109.  
  110.         SetUp   <DS, ES>
  111.         CLD
  112.         LES     DI, dest
  113.         TEST    BYTE PTR ES:[DI], -1    ; see if anything to do
  114.         JZ      @@nix                   ; no, is empty
  115.  
  116.         SUB     AL, AL                  ; scan for NUL
  117.         SUB     CX, CX                  ; as much as 64 KB
  118.         REPNZ SCASB
  119. @@nix:
  120.         JMP     copy_string             ; copy other one behind
  121.  
  122. StrCat  ENDP
  123.  
  124.  
  125. StrComp PROC    FAR     dest: pntr, source: pntr
  126. ; FUNCTION StrComp (dest, source: PChar): integer;
  127.  
  128.         SetUp   <DS, ES>
  129.         CLD
  130.         LDS     SI, source
  131.         LES     DI, dest
  132. @@next:
  133.         LODSB                           ; get current source char
  134.         SCASB                           ; compare with target char
  135.         JA      @@more                  ; not equal?
  136.         JB      @@less                  ; what's the difference?
  137.  
  138.         OR      AL, AL                  ; hit terminator?
  139.         JNZ     @@next                  ; not yet, continue
  140. @@null:
  141.         SUB     Rint, Rint              ; all compared ok
  142. @@done:
  143.         CleanUp <ES, DS>
  144.  
  145. @@less:
  146.         MOV     Rint, -1                ; dest was "greater"
  147.         JMP     SHORT @@done
  148. @@more:
  149.         MOV     Rint, 1                 ; dest was "less"
  150.         JMP     SHORT @@done
  151.  
  152. StrComp ENDP
  153.  
  154.  
  155. StrCopy PROC    FAR     dest: pntr, source: pntr
  156. ; FUNCTION StrCopy (dest, source: PChar): PChar;
  157.  
  158.         SetUp   <DS, ES>
  159.         CLD
  160.         LES     DI, dest
  161. copy_string:                            ; an entry from elsewhere...
  162.         LDS     SI, source              ; (see below)
  163. @@next:
  164.         LODSB                           ; copy characters
  165.         STOSB
  166.         OR      AL, AL                  ; till NUL terminator
  167.         JNZ     @@next
  168.  
  169.         LES     DI, dest
  170.         MOV     Rseg, ES
  171.         MOV     Roff, DI
  172.         CleanUp <ES, DS>
  173.  
  174. StrCopy ENDP
  175.  
  176.  
  177. StrECopy        PROC    FAR     dest: pntr, source: pntr
  178. ; FUNCTION StrECopy (dest, source: PChar): PChar;
  179.  
  180.         SetUp   <DS, ES>
  181.         LDS     SI, source
  182.         LES     DI, dest
  183.         CLD
  184. @@next:
  185.         LODSB                           ; copy characters
  186.         STOSB
  187.         OR      AL, AL                  ; till NUL terminator
  188.         JNZ     @@next
  189.  
  190.         DEC     DI                      ; went one too far
  191.         MOV     Rseg, ES                ; set up return registers
  192.         MOV     Roff, DI                ; for pointer value
  193.         CleanUp <ES, DS>
  194.  
  195. StrECopy        ENDP
  196.  
  197.  
  198. StrEnd  PROC    FAR     source: pntr
  199. ; FUNCTION StrEnd (source: PChar): PChar;
  200.  
  201.         SetUp   ES
  202.         CLD
  203.         MOV     CX, -1
  204.         LES     DI, source
  205.         SUB     AL, AL                  ; look out for NUL
  206.         REPNZ SCASB
  207.         DEC     DI                      ; was just behind
  208.         MOV     Rseg, ES                ; and return pointer to
  209.         MOV     Roff, DI                ; terminator
  210.         CleanUp ES
  211.  
  212. StrEnd  ENDP
  213.  
  214.  
  215. StrLCat PROC    FAR     dest: pntr, source: pntr, n: WORD
  216. ; FUNCTION StrLCat (dest, source: PChar; n: byte): PChar;
  217.  
  218.         SetUp   <DS, ES>
  219.         CLD
  220.         LES     DI, dest
  221.         TEST    BYTE PTR ES:[DI], -1    ; see if anything to do
  222.         JZ      @@nix                   ; no, is empty
  223.  
  224.         SUB     AL, AL                  ; scan for NUL
  225.         SUB     CX, CX                  ; as much as 64 KB
  226.         REPNZ SCASB
  227. @@nix:
  228.         JMP     copy_n_chars            ; copy other one behind
  229.  
  230. StrLCat ENDP
  231.  
  232.  
  233. StrLComp PROC   FAR     dest: pntr, source: pntr, n: WORD
  234. ; FUNCTION StrLComp (dest, source: PChar; n: byte): integer;
  235.  
  236.         SetUp   <DS, ES>
  237.         MOV     CX, n                   ; get compare count
  238.         JCXZ    @@null                  ; nothing to do?
  239.  
  240.         LDS     SI, source
  241.         LES     DI, dest
  242.         CLD
  243. @@next:
  244.         LODSB                           ; get current source char
  245.         SCASB                           ; compare with target char
  246.         JA      @@more                  ; not equal?
  247.         JB      @@less                  ; what's the difference?
  248.  
  249.         OR      AL, AL                  ; hit terminator?
  250.         LOOPNZ  @@next                  ; not yet, continue
  251. @@null:
  252.         SUB     Rint, Rint              ; all compared ok
  253. @@done:
  254.         CleanUp <ES, DS>
  255.  
  256. @@less:
  257.         MOV     Rint, -1                ; dest was "greater"
  258.         JMP     SHORT @@done
  259. @@more:
  260.         MOV     Rint, 1                 ; dest was "less"
  261.         JMP     SHORT @@done
  262.  
  263. StrLComp ENDP
  264.  
  265.  
  266. StrLCopy PROC   FAR     dest: pntr, source: pntr, n: WORD
  267.  
  268.         SetUp   <DS, ES>
  269.         CLD
  270.         LES     DI, dest
  271. copy_n_chars:
  272.         MOV     CX, n
  273.         JCXZ    @@nix
  274.         LDS     SI, source
  275.         REP MOVSB
  276. @@nix:
  277.         SUB     AL, AL
  278.         STOSB
  279.         LES     DI, dest                ; reset to beginning
  280.         MOV     Rseg, ES                ; to be passed
  281.         MOV     Roff, DI                ; back
  282.         CleanUp <ES, DS>
  283.  
  284. StrLCopy ENDP
  285.  
  286.  
  287. StrLen  PROC    FAR     source: pntr
  288. ; FUNCTION StrLen (source: PChar): word;
  289.  
  290.         SetUp   ES                      ; not _really_ needed...
  291.         SUB     CX, CX                  ; assume empty
  292.         LES     DI, source              ; now get the address
  293.         TEST    BYTE PTR ES:[DI], -1    ; and test the first char
  294.         JZ      @@nix                   ; really empty!
  295.  
  296.         CLD                             ; _always_ go upstairs!
  297.         DEC     CX
  298.         SUB     AL, AL                  ; scan for NUL byte
  299.         REPNZ SCASB                     ; within string
  300.         INC     CX                      ; convert counter register
  301.         NOT     CX                      ; to distance from start
  302. @@nix:
  303.         MOV     Rint, CX                ; and return in result reg
  304.         CleanUp ES
  305.  
  306. StrLen  ENDP
  307.  
  308.  
  309. StrPas  PROC    FAR     cstring: pntr   RETURNS pstring: pntr
  310. ; FUNCTION StrPas (source: PChar): string;
  311.  
  312.         SetUp   <DS, ES>
  313.         LDS     SI, cstring             ; this is the source
  314.         MOV     AX, DS
  315.         OR      AX, SI                  ; check for NIL
  316.         JZ      @@thru                  ; if so we're done
  317.  
  318.         LES     DI, pstring             ; the target is implicitely
  319.         CLD                             ; passed by the compiler!
  320.         SUB     AX, AX                  ; clear length counter
  321.         STOSB                           ; skip length byte
  322. @@next:
  323.         LODSB                           ; now check this char
  324.         OR      AL, AL                  ; hit NUL terminator?
  325.         JZ      @@thru                  ; then we're done
  326.  
  327.         INC     AH                      ; else increment counter
  328.         JZ      @@over
  329.  
  330.         STOSB                           ; and copy this one over
  331.         JMP     @@next                  ; continue
  332. @@over:
  333.         DEC     AH                      ; don't count terminator
  334. @@thru:
  335.         MOV     AL, AH                  ; put count into correct register
  336.         LES     DI, pstring             ; point at start of result
  337.         STOSB                           ; and put count there
  338.         CleanUp <ES, DS>
  339.  
  340. StrPas  ENDP
  341.  
  342. COMMENT %
  343.  
  344. StrPCopy PROC   FAR     dest: pntr, source: pntr
  345. ; FUNCTION StrPCopy (dest: PChar; source: string): PChar;
  346.  
  347.         SetUp   <DS, ES>
  348.         LES     DI, dest
  349.         LDS     SI, source
  350.         SUB     CX, CX
  351.         LODSB
  352.         MOV     CL, AL
  353.         JCXZ    @@nix
  354.         CLD
  355.         REP MOVSB
  356.         SUB     AL, AL
  357. @@nix:
  358.         STOSB
  359.         LES     DI, dest
  360.         MOV     Rseg, ES
  361.         MOV     Roff, DI
  362.         CleanUp <ES, DS>
  363.  
  364. StrPCopy ENDP
  365. %
  366.  
  367. StrScan PROC    FAR     source: pntr, chr: WORD
  368. ; FUNCTION StrScan (source: PChar; ch: char): PChar;
  369.  
  370.         SetUp   DS
  371.         CLD
  372.         LDS     SI, source
  373.         MOV     DX, chr
  374. @@next:
  375.         LODSB
  376.         OR      AL, AL                  ; see if at end already
  377.         JZ      @@null                  ; yes, hit terminator
  378.  
  379.         CMP     AL, DL                  ; is it requested char?
  380.         JNZ     @@next                  ; no, get next one
  381. @@found:
  382.         MOV     Rseg, DS                ; return pointer
  383.         MOV     Roff, SI                ; to target char
  384.         DEC     Roff                    ; went one too far
  385.         CleanUp DS
  386. @@null:
  387.         SUB     Rseg, Rseg              ; else return NIL
  388.         MOV     Roff, Rseg
  389.         CleanUp DS
  390.  
  391. StrScan ENDP
  392.  
  393.  
  394. StrRScan PROC    FAR     source: pntr, chr: WORD
  395. ; FUNCTION StrRScan (source: PChar; ch: char): PChar;
  396.  
  397.         SetUp   ES
  398.         LES     DI, source              ; now get the address
  399.         TEST    BYTE PTR ES:[DI], -1    ; and test the first char
  400.         JZ      @@null                  ; cannot be!
  401.  
  402.         CLD
  403.         MOV     CX, -1
  404.         SUB     AL, AL                  ; find terminating NUL
  405.         REPNZ SCASB
  406.         DEC     DI                      ; revert to terminator
  407.         NOT     CX                      ; to real string length
  408.         MOV     AX, chr                 ; get what to search for
  409.         STD                             ; do it backwards now!
  410.         REPNZ SCASB                     ; and off we go!
  411.         JNZ     @@null                  ; nope, not found
  412. @@found:
  413.         MOV     Rseg, ES                ; return pointer
  414.         MOV     Roff, DI                ; to target char
  415.         INC     Roff                    ; went one too far
  416.         CLD                             ; just for safety
  417.         CleanUp ES
  418. @@null:
  419.         SUB     Rseg, Rseg              ; else return NIL
  420.         MOV     Roff, Rseg
  421.         CleanUp ES
  422.  
  423. StrRScan ENDP
  424.  
  425.  
  426. StrSkip PROC    FAR     source: pntr
  427. ; FUNCTION StrSkip (source: PChar): PChar;
  428.  
  429.         SetUp   ES
  430.         MOV     CX, -1
  431.         LES     DI, source
  432.         SUB     AL, AL                  ; look out for NUL
  433.         CLD
  434.         REPNZ SCASB
  435.         MOV     Rseg, ES                ; and return pointer to
  436.         MOV     Roff, DI                ; just behind
  437.         CleanUp ES
  438.  
  439. StrSkip ENDP
  440.  
  441.         END
  442.